package Util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class ActiveDirectory {
    private Properties properties;
    private InitialDirContext dirContext;
    private String domainController;
    
    private String getDomainController() {
        return domainController;
    }

    private void setDomainController(String domainController) {
        this.domainController = domainController;
    }    
    
    public ActiveDirectory(String username, String password, String domainController, String domainControllerPort) throws Exception{             
        properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        properties.put(Context.PROVIDER_URL, "LDAP://"+domainController+":"+domainControllerPort);
        properties.put(Context.SECURITY_AUTHENTICATION, "simple");
        properties.put(Context.SECURITY_PRINCIPAL, username + "@" + domainController);
        //ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=administrateur,cn=users,dc=societe,dc=fr");
        //ldapEnv.put(Context.SECURITY_PRINCIPAL, "cn=jean paul blanc,ou=MonOu,dc=dom,dc=fr");
        properties.put(Context.SECURITY_CREDENTIALS, password);
        properties.put(Context.SECURITY_PROTOCOL, "simple");        

        // initializing active directory LDAP connection        
        try {
            dirContext = new InitialDirContext(properties);              
            setDomainController(domainController);            
        } catch (NamingException e) {            
            throw new Exception(Language.getProperty("error.DA.noConectivity") + e.getMessage());
        }                                       
    }   
        
    public ArrayList searchUser(String searchValue) throws Exception{
        try{
            //initializing search controls
            SearchControls searchCtls = new SearchControls();
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

            //Specify the attributes to return
            String returnAttributes[]={"displayName", "title", "company","department","streetAddress","street", "telephoneNumber","mail"};
            searchCtls.setReturningAttributes(returnAttributes);          

            //specify the LDAP search filter
            String searchFilter = "(&(objectClass=user)(!(objectClass=computer))(sAMAccountName="+searchValue+"))";
            
            // Search for objects using the filter
            NamingEnumeration<SearchResult> answer = dirContext.search(getDomainSearchBase(), searchFilter, searchCtls);
            dirContext.close();
            
            ArrayList tempArrayList = Collections.list( answer );
            answer.close();            
                                                                                                
            if(tempArrayList.isEmpty()){                
                throw new Exception(Language.getProperty("error.DA.sarchUserNoFound"));
            }else if(tempArrayList.size() > 1){
                throw new Exception(Language.getProperty("error.DA.sarchUserToMany"));
            }                      
            return tempArrayList;
        }
        catch (Exception e){
          throw new Exception(Language.getProperty("error.DA.queryError")+e.getMessage());          
        }        
    }
        
    private String getDomainSearchBase() throws Exception{           
        String[] dcs = getDomainController().split("\\.");
        String domainSearchBase = new String();
        for (int i = 0; i < dcs.length; i++) {
            if (!domainSearchBase.isEmpty()) {
                domainSearchBase = domainSearchBase + ",";
            }            
            domainSearchBase = domainSearchBase + "dc=" + dcs[i];                        
        }                   
        return domainSearchBase;
    }
    
}
